`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2025/04/22 14:41:09
// Design Name: 
// Module Name: top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module top(
    input                               clk                        ,
    input                               rst                        ,
    input              [   3: 0]        key_in                     ,
    output             [   7: 0]        seg_out                    ,
    output             [   7: 0]        sel_out                    ,
    output             [   7: 0]        led_out                    ,
    output                              tx                         ,
    output reg         [   9: 0]        zhu_num                    ,
    output                              scl                        ,
    inout                               sda                         
    );
    // adc
    reg                                 start                       ;
    wire                                adc_ready                   ;
    reg                                 rw_flag                     ;
    reg                [   7: 0]        word_addr                   ;
    reg                [  15: 0]        wdata                       ;
    wire               [  15: 0]        rdata                       ;
    wire                                rdata_valid                 ;
    wire                                ack_error                   ;
    wire                                ctrl                        ;
    // seg
    wire               [  31: 0]        seg_buff                    ;
    reg                [   3: 0]        seg_data   [0:7]  ;
    assign                              seg_buff                    = {seg_data[0],seg_data[1],seg_data[2],seg_data[3],seg_data[4],seg_data[5],seg_data[6],seg_data[7]};
    // led
    reg                [   7: 0]        led_num                     ;
    assign                              led_out                     = ~led_num;
    // key
    wire               [   3: 0]        key_val                     ;
    // uart
    reg                [   7: 0]        tx_data                     ;
    reg                                 tx_data_vld                 ;
    wire                                ready                       ;

    parameter                           MS_MAX                     = 500_000;
    reg                [  20: 0]        ms_cnt                      ;

    reg                                 ui_mod                      ;
    // 1ms
    always @(posedge clk or posedge rst)begin
        if(rst)begin
            ms_cnt <= 0;
        end else begin
            if(ms_cnt == MS_MAX - 1)begin
                ms_cnt <= 0;
            end else begin
                ms_cnt <= ms_cnt + 1;
            end
        end
    end
    // key
    always @(posedge clk or posedge rst)begin
        if(rst)begin
            ui_mod <= 0;
        end else begin
            if(key_val == 1)
                ui_mod <= ~ui_mod;
        end
    end
    // led
    always @(posedge clk or posedge rst)begin
        if(rst)begin
            start <= 1;
            rw_flag <= 1;
            word_addr <= 0;
            led_num <= 0;
        end else begin
            if(ms_cnt == MS_MAX - 1)begin
                if(adc_ready)
                    start <= 1;
                else
                    start <= 0;
                led_num <= rdata[11:4];
            end
        end
    end
    // seg
    always @(posedge clk or posedge rst)begin
        if(rst)begin
            seg_data[0] <= 10;
            seg_data[1] <= 10;
            seg_data[2] <= 10;
            seg_data[3] <= 10;
            seg_data[4] <= 10;
            seg_data[5] <= 10;
            seg_data[6] <= 10;
            seg_data[7] <= 10;
            zhu_num <= 0;
        end else begin
            if(ms_cnt == MS_MAX - 1)begin
                zhu_num[8] <= 0;
                zhu_num[9] <= 1;
                if(ui_mod == 0)begin
                    zhu_num[7:0] <= zhu_num[7:0] + 1;
                    seg_data[0] <= zhu_num[0];
                    seg_data[1] <= zhu_num[1];
                    seg_data[2] <= zhu_num[2];
                    seg_data[3] <= zhu_num[3];
                    seg_data[4] <= zhu_num[4];
                    seg_data[5] <= zhu_num[5];
                    seg_data[6] <= zhu_num[6];
                    seg_data[7] <= zhu_num[7];
                end else begin
                    zhu_num[7:0] <= led_num;
                    seg_data[0] <= led_num[0];
                    seg_data[1] <= led_num[1];
                    seg_data[2] <= led_num[2];
                    seg_data[3] <= led_num[3];
                    seg_data[4] <= led_num[4];
                    seg_data[5] <= led_num[5];
                    seg_data[6] <= led_num[6];
                    seg_data[7] <= led_num[7];
                end
            end
        end
    end


key u_key(
    .clk                                (clk                       ),
    .rst                                (rst                       ),
    .key_in                             (key_in                    ),
    .key_val                            (key_val                   ) 
);


seg u_seg(
    .clk                                (clk                       ),
    .rst                                (rst                       ),
    .seg                                (seg_out                   ),
    .sel                                (sel_out                   ),
    .seg_buff                           (seg_buff                  ) 
);

uart_tx u_uart_tx(
    .clk                                (clk                       ),
    .rst                                (rst                       ),
    .tx_data                            (tx_data                   ),
    .tx_data_vld                        (tx_data_vld               ),
    .ready                              (ready                     ),
    .tx                                 (tx                        ) 
);


iic_drive#(
    .P_SYS_CLK                          (28'd50_000_000            ),
    .P_IIC_SCL                          (28'd125_000               ),
    .P_DEVICE_ADDR                      (7 'b1010_100              ),
    .P_ADDR_BYTE_NUM                    (1                         ),
    .P_DATA_BYTE_NUM                    (2                         ) 
)
u_iic_drive(
    .iic_clk                            (clk                       ),
    .iic_rst                            (rst                       ),
    .iic_start                          (start                     ),
    .iic_ready                          (adc_ready                 ),
    .iic_rw_flag                        (rw_flag                   ),
    .iic_word_addr                      (word_addr                 ),
    .iic_wdata                          (wdata                     ),
    .iic_rdata                          (rdata                     ),
    .iic_rdata_valid                    (rdata_valid               ),
    .iic_ack_error                      (ack_error                 ),
    .iic_scl                            (scl                       ),
    .iic_sda                            (sda                       ) 
);

endmodule
